package Stream;

import Lambda.MethodReferences.Employee;
import Lambda.MethodReferences.EmployeeData;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @projectName: Java8
 * @package: Stream
 * @className: StreamAPITest3
 * @author: 冷环渊 doomwatcher
 * @description: TODO
 * @date: 2021/12/12 17:10
 * @version: 1.0
 */
public class StreamAPITest3 {

    /**
     * @author 冷环渊 Doomwatcher
     * @context: 匹配与查找
     * @date: 2021/12/12 17:11
     * @param
     * @return: void
     */
    @Test
    public void test1() {
        //- allMatch(Predicate p) 检查是否匹配所有元素
        List<Employee> employees = EmployeeData.getEmployees();
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println("allMatch(Predicate p) 检查是否匹配所有元素: " + allMatch);
        //-  anyMatch(Predicate p) 检查是否至少匹配一个元素
        boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() > 10000);
        System.out.println(" anyMatch(Predicate p) 检查是否至少匹配一个元素: " + anyMatch);
        //- noneMatch(Predicate p) 检查是否没有匹配所有元素
        boolean noneMatch = employees.stream().noneMatch(e -> e.getName().startsWith("雷"));
        System.out.println("noneMatch(Predicate p) 检查是否没有匹配所有元素: " + noneMatch);
        //-  findFirst() 返回第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println("findFirst() 返回第一个元素: " + first);
        //- findAny() 返回当前流中的任意元素
        Optional<Employee> any = employees.parallelStream().findAny();
        System.out.println("findFirst() 返回第一个元素: " + any);
        //- count() 返回流中元素总数
        Long salary = employees.stream().filter(e -> e.getSalary() > 5000).count();
        System.out.println("count() 返回流中元素总数: " + salary);
    }


    /**
     * @author 冷环渊 Doomwatcher
     * @context:
     * @date: 2021/12/12 23:30
     * @param
     * @return: void
     */
    @Test
    public void test2() {
        //- max(Comparator c) 返回流中最大值
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Double> stream = employees.stream().map(e -> e.getSalary());
        Optional<Double> max = stream.max(Double::compare);
        System.out.println("返回流中最大值:" + max);
        //- min(Comparator c) 返回流中最小值
        Optional<Employee> min = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println("返回流中最小值: " + min);
        //- forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭代， 称为外部迭代。相反，Stream API 使用内部迭 代——它帮你把迭代做了)
        employees.stream().forEach(System.out::println);
        //使用集合的方式
        employees.forEach(System.out::println);
    }

    /**
     * @author 冷环渊 Doomwatcher
     * @context: 规约
     * @date: 2021/12/12 23:56
     * @param
     * @return: void
     */
    @Test
    public void tset3() {

        //- reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来，得到一 个值。返回 T
        // 小练习 计算1-10的自然数总和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer resultReduce = list.stream().reduce(0, Integer::sum);
        System.out.println("resultReduce: " + resultReduce);
        //- reduce(BinaryOperator b) 可以将流中元素反复结合起来，得到一 个值。返回 Optional
        //    小练习 计算公司所有员工的工资总和
        List<Employee> employees = EmployeeData.getEmployees();
        Optional<Double> slaryStream = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(slaryStream);
    }

    /**
     * @author 冷环渊 Doomwatcher
     * @context: 收集
     * @date: 2021/12/13 0:23
     * @param
     * @return:
     */
    @Test
    public void test4() {
        /* collet（Collector c） 将流转换成其他的形式，接收一个 Collector接口实现，用于给Stream中元素做汇总方法
         * 练习一 查找工资大于6000的员工 返回一个 list 或者set
         * */
        List<Employee> employees = EmployeeData.getEmployees();
        //大于六千的list
        List<Employee> employeeList = employees.stream().filter(employee -> employee.getSalary() > 6000).collect(Collectors.toList());
        employeeList.forEach(System.out::println);
        System.out.println();
        //小于六千的set
        Set<Employee> employeeSet = employees.stream().filter(employee -> employee.getSalary() < 6000).collect(Collectors.toSet());
        employeeSet.forEach(System.out::println);

    }
}
